<?php

namespace app\command;

use app\helpers\Common;
use app\common\service\Cron as CronService;

use support\think\Db;
use think\Exception;

class Crontab
{
    public static function cron()
    {
        $log_folder = 'crontab';
        log_info("---> Crontab: beigin", 'INFO', $log_folder);

        $time = time();
        // 筛选未过期且未完成的任务
        $crontabList = \app\common\model\Crontab::where('status', '=', 'normal')->order('weigh DESC, id DESC')->select();
        $execTime = time();
        foreach ($crontabList as $crontab) {
            $update = [];
            $execute = false;
            if ($time < $crontab['begin_time']) {
                // 任务未开始
                continue;
            }
            // 判断上次执行时间 1分钟内最多执行一次
            if ($crontab['execute_time'] && date('YmdHi', $crontab['execute_time']) === date('YmdHi', $execTime)) {
                continue;
            }
            if ($crontab['maximums'] && $crontab['executes'] > $crontab['maximums']) {
                // 任务已超过最大执行次数
                $update['status'] = 'completed';
            } else {
                if ($crontab['end_time'] > 0 && $time > $crontab['end_time']) {
                    // 任务已过期
                    $update['status'] = 'expired';
                } else {
                    // 重复执行
                    // 是否达到执行时间
                    if (!CronService::checkSchedule($crontab['minute'], $crontab['hour'], $crontab['day'], $crontab['month'], $crontab['week'], $crontab['year'])) {
                        continue;
                    }
                    $execute = true;
                }
            }

            // 如果允许执行
            if ($execute) {
                $update['execute_time'] = $time;
                $update['executes'] = $crontab['executes'] + 1;
                $update['status'] = ($crontab['maximums'] > 0 && $update['executes'] >= $crontab['maximums']) ? 'completed' : 'normal';
            }
            // 如果需要更新状态
            if (!$update) {
                continue;
            }
            // 更新状态
            $crontab->save($update);

            // 将执行放在后面是为了避免超时导致多次执行
            if (!$execute) {
                continue;
            }
            $result = false;
            $message = '';
            try {
                $route = $crontab['content'];
                $param = $crontab['param'] ? json_decode($crontab['param'], true) : [];
                if ($route == 'export') {
                    // 导出任务
                    if (isset($param['id']) && isset($param['table'])) {

                    }
                }
            } catch (Exception $e) {
                $message = $e->getMessage();
            }
            $log = [
                'crontab_id' => $crontab['id'],
                'created_at' => time(),
                'execute_time' => $time,
                'completed_time' => time(),
                'content' => $message,
                'status' => $result ? 1 : 0,
            ];
            log_info("---> Crontab: result " . json_encode($log, JSON_UNESCAPED_UNICODE), 'INFO', $log_folder);
            break;
        }
        log_info("---> Crontab: end", 'INFO', $log_folder);
    }
}